/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Hash;

import java.util.Arrays;
import java.util.Stack;
import AnalisadorSemantico.TiposSemanticos;
import AnalisadorLexico.CodigoErros;
import AnalisadorLexico.Lexico;
import java.util.LinkedList;
import TabelaDeSimbolos.nodoEncadeado;
import java.util.HashSet;
import java.util.Set;
import static TabelaDeSimbolos.classeTabelaSimbolos.tabelaSimbolos;

/**
 *
 * @author 341232
 */
public class Metodos {

    public  Stack<String> tks = new Stack<String>();
     
    protected int geraHashCode(String lexema) {
        int hc = lexema.hashCode() % tabelaSimbolos.capacity();

        // Condição para tratar valores negativos
        if (hc < 0) {
            hc = hc * -1;
        }

        return hc;
    }

    public nodoEncadeado verificaTipo(nodoEncadeado nodoAux) {

        if (nodoAux.getTipo() != null && nodoAux.getTipo().equals("digito")) {
            if (nodoAux.getLexema().contains(".")) {
                nodoAux.setTipo(TiposSemanticos.Real.getTipo());
                defineTipo(nodoAux);
            } else {
                nodoAux.setTipo(TiposSemanticos.Inteiro.getTipo());
                defineTipo(nodoAux);
            }
        }

        return nodoAux;
    }

    public void defineClasse(nodoEncadeado nodo) {
        nodoEncadeado novoNodo = pesquisa(nodo.getLexema().toLowerCase());

        int posTabela = novoNodo.getPosTabela();
        int posLista = novoNodo.getPosLista();

        tabelaSimbolos.elementAt(posTabela).get(posLista).setClasse(nodo.getClasse());

    }

    public void defineTipo(nodoEncadeado nodo) {
        nodoEncadeado novoNodo = pesquisa(nodo.getLexema().toLowerCase());

        int posTabela = novoNodo.getPosTabela();
        int posLista = novoNodo.getPosLista();

        tabelaSimbolos.elementAt(posTabela).get(posLista).setTipo(nodo.getTipo());

    }

    public void insercao(byte token, String lexema, String Tipo) {
        Lexico lexico = new Lexico();
        if (pesquisa(lexema) != null) {
            lexico.mensagemErro(CodigoErros.identificadorJaDeclarado.getCodigoErro(), lexema);
        } else {
            int hashCodeGerado = 0;

            nodoEncadeado nodo = new nodoEncadeado(token, lexema.toLowerCase());
            nodo.setTipo(Tipo);

            hashCodeGerado = geraHashCode(lexema.toLowerCase());

            tabelaSimbolos.elementAt(hashCodeGerado).add(nodo);
        }
    }

    public void inserirReservadas() {

        insercao((byte) 1, "inteiro", "");
        insercao((byte) 4, "enquanto", "");
        insercao((byte) 5, "se", "");
        insercao((byte) 6, "senao", "");
        insercao((byte) 7, "e", "");
        insercao((byte) 8, "ou", "");
        insercao((byte) 9, "nao", "");
        insercao((byte) 10, "==", "");
        insercao((byte) 11, "(", "");
        insercao((byte) 12, ")", "");
        insercao((byte) 13, "<", "");
        insercao((byte) 14, ">", "");
        insercao((byte) 15, "<>", "");
        insercao((byte) 16, ">=", "");
        insercao((byte) 17, "<=", "");
        insercao((byte) 18, ",", "");
        insercao((byte) 19, "=", "");
        insercao((byte) 20, "-", "");
        insercao((byte) 21, "*", "");
        insercao((byte) 22, "/", "");
        insercao((byte) 23, "$", "");
        insercao((byte) 24, "Inicio", "");
        insercao((byte) 25, "Fim", "");
        insercao((byte) 32, "+", "");
        insercao((byte) 33, "Escala", "");
        insercao((byte) 34, "Pausa", "");
        insercao((byte) 35, "Rottrans", "");
        insercao((byte) 36, "Faca", "");
        insercao((byte) 37, "Entao", "");
        insercao((byte) 38, "Real", "");
        insercao((byte) 39, "DPonto", "");
        insercao((byte) 40, "DFace", "");
        insercao((byte) 41, "DObjeto", "");
        insercao((byte) 42, "DCor", "");
        insercao((byte) 43, "DLuz", "");
        insercao((byte) 44, "DVar", "");
        insercao((byte) 45, "Luz", "");
        insercao((byte) 46, " ", "");
        insercao((byte) 47, "DConst", "");
    }

    public nodoEncadeado pesquisa(String lexema) {

        LinkedList<nodoEncadeado> listateste = new LinkedList<nodoEncadeado>();
        nodoEncadeado nodoRetornado = new nodoEncadeado((byte) 0, "", 0, 0, "", "");
        int achouNaTabela = 0;
        int posTabela = 0;
        int posLista = 0;
        int tokenEncontrado = 0;
        String classe = "";
        String tipo = "";


        for (int i = 0; i < 44; i++) {
            listateste = tabelaSimbolos.elementAt(i);

            for (int j = 0; j < listateste.size(); j++) {
                if (listateste.get(j).getLexema().equals(lexema.toLowerCase())) {
                    achouNaTabela = 1;
                    posTabela = i;
                    posLista = j;
                    tokenEncontrado = listateste.get(j).getToken();
                    classe = listateste.get(j).getClasse();
                    tipo = listateste.get(j).getTipo();
                }
            }
        }

        if (achouNaTabela == 0) {
            return null;
        } else {
            nodoRetornado.setToken((byte) tokenEncontrado);
            nodoRetornado.setLexema(lexema);
            nodoRetornado.setPosLista(posLista);
            nodoRetornado.setPosTabela(posTabela);
            nodoRetornado.setClasse(classe);
            nodoRetornado.setTipo(tipo);

        }
        return nodoRetornado;

        // return null;

    }//fim Metodo




  private static double evalrpn(Stack<String> tks) throws Exception  {
    String tk = tks.pop();
    double x,y;
    try  {x = Double.parseDouble(tk);}
    catch (Exception e)  {
      y = evalrpn(tks);  x = evalrpn(tks);
      if      (tk.equals("+"))  x += y;
      else if (tk.equals("-"))  x -= y;
      else if (tk.equals("*"))  x *= y;
      else if (tk.equals("/"))  x /= y;
      else throw new Exception();
    }
    return x;
  }

    

}//fim de classe

